package it.david.javassist

import javassist.*
import javassist.bytecode.MethodInfo

import java.lang.reflect.Modifier

public class JavassistInject {
    private static ClassPool mPool = ClassPool.getDefault()
    private static String mInjectStr = "System.out.println(\"I Love David\");";
    private static String mInjectStr2 = "return \"I Love David\" ";

    public static void injectDir(String path, String packageName) {
        mPool.appendClassPath(path)
        File dir = new File(path)
        if (dir.isDirectory()) {
            dir.eachFileRecurse { File file ->
                String filePath = file.absolutePath
                if (filePath.endsWith(".class")
                        && !filePath.contains('R$')
                        && !filePath.contains('R.class')
                        && !filePath.contains("BuildConfig.class")
                        && !filePath.contains('android$')
                        && !filePath.contains('Monitor')) {
                    //判断当前目录是否是我们在应用宝里面
                    def index = filePath.indexOf(packageName)
                    def isMyPackage = index != -1;
                    if (isMyPackage) {
                        def end = filePath.length() - 6 // .class = 6
                        def className = filePath.substring(index, end).replace('\\', '.').replace('/', '.')
                        //开始修改
                        CtClass c = mPool.getCtClass(className)
                        System.out.println "className : " + className
                        if (c.isFrozen()) {
                            c.defrost()
                        }

                        CtConstructor[] cts = c.getDeclaredConstructors()
                        if (cts == null || cts.length == 0) {
                            //手动创建一个构造函数
                            CtConstructor constructor = new CtConstructor(new CtClass[0], c)
                            constructor.insertBeforeBody(mInjectStr)
                            c.addConstructor(constructor)
                        } else {
                            cts[0].insertBeforeBody(mInjectStr)
                        }
                        CtMethod[] methods = c.getMethods()
                        for (int i = 0; i < methods.length; i++) {
                            CtMethod method = methods[i];
                            MethodInfo methodInfo = method.methodInfo;
                        }

//                        CtMethod toStringMethod = c.getMethod("toString", null)
//                        if (toStringMethod != null && !toStringMethod.empty) {
////                            genealadapter.dengwei.it.javassistdemo.monitor.Monitor
//                            toStringMethod.insertBefore("generaladapter.dengwei.it.javassistdemo.monitor.Monitor monitor = new generaladapter.dengwei.it.javassistdemo.monitor.Monitor();\n" +
//                                    "monitor.onMonitor(null);")
//                        }
                        c.

                        CtMethod[] onClickMethods = c.getDeclaredMethods("onClick")
                        if (onClickMethods != null && onClickMethods.length > 0) {
                            for (int i = 0; i < onClickMethods.length; i++) {
                                def onClickMethod = onClickMethods[i];
                                if (onClickMethod != null && !onClickMethod.empty) {
                                    onClickMethod.insertBefore("System.out.println(\"lkalaalalalla\");")
                                }
                            }
                        }




                        c.writeFile(path)
                        c.detach()
                    }
                }
            }
        }
    }
}